<template>
  <up-overlay :show="voiceShow" @tap="voiceShow = false">
    <view class="voiceCom" :class="{ closeVoice: movingDistance > 140 }">
      <view class="git">
        <view class="gitIcon"></view>
        <view class="voiceTime">{{ voiceTime }}</view>
      </view>
      <view class="gitText">
        <view class="voiceClose">松开 取消</view>
        <view class="closeIcon"><i></i></view>
        <view class="voiceSend">松开 发送</view>
      </view>
      <view class="voiceBg">
        <i></i>
      </view>
    </view>
  </up-overlay>
</template>

<script setup lang="ts">
import { ref, onUnmounted ,getCurrentInstance} from "vue";
import { onHide } from "@dcloudio/uni-app";
import { UploadTokenApi, handleFileUploadForApp ,} from "@/api/SystemApi";
const instance = getCurrentInstance()?.appContext.config.globalProperties;

defineProps({
  movingDistance: {
    type: Number,
    default: 0,
  },
});

const emit = defineEmits();
const voiceShow = ref<boolean>(false);
const voiceTime = ref<string>("00:00"); // 存储录音时长
const recorderManager = uni.getRecorderManager();
let statusValue: string = "";
let voicePath: string = "";
let timer: any = null; // 定时器
let startTime: number = 0; // 录音开始时间
let recordingDuration: number = 0; // 录音时长

// 打开语音录制弹窗
const openVoiceFn = (boo: boolean, status: string) => {
  statusValue = status;
  if (boo) {
    checkAudioPermission(boo); // 检查权限
  } else {
    voiceShow.value = boo;
    endRecording();
  }
};

// 检查录音权限
const checkAudioPermission = async (boo: boolean) => {
  startRecording(boo);
};

// 开始录音
const startRecording = (boo: boolean) => {
  clearInterval(timer);
  recorderManager.onStart(() => {
    console.log("开始录音");
    timer = setInterval(updateRecordingDuration, 1000);
    voiceShow.value = boo;
    console.log("Recorder started");
  });

  recorderManager.onStop(handleRecordingStop);
  recorderManager.start({});
  startTime = Date.now();
};

// 更新录音时长
const updateRecordingDuration = () => {
  recordingDuration = Math.floor((Date.now() - startTime) / 1000);
  const minutes = Math.floor(recordingDuration / 60);
  const seconds = recordingDuration % 60;
  voiceTime.value = `${padZero(minutes)}:${padZero(seconds)}`;

  // 如果时长超过 60 秒，自动发送
  if (recordingDuration >= 60) {
    clearInterval(timer);
    openVoiceFn(false, "send"); // 发送语音
  }
};

// 处理录音结束
const handleRecordingStop = async (res:any) => {
  console.log("Recorder stopped", res);
  voicePath = res.tempFilePath;
  clearInterval(timer); // 停止计时器
  console.log("更新最终时长", recordingDuration);
  if (recordingDuration <= 0) {
    uni.showToast({
      title: "说话时间太短",
      icon: "none",
    });
    return;
  }

  if (statusValue === "send") {
    uni.showLoading({ mask: true });

    try {
      let obj = await UploadTokenApi({
        file_suffix: voicePath.split(".").pop(),
        file_purpose: 2,
      });
      console.log(obj);
      obj = {
        ...obj,
        uploadUrl: atob(obj.uploadurl),
        message_type: 4,
        path: voicePath,
        duration: recordingDuration,
      };
      uni.showLoading({ mask: true });
      instance?.playVoice(2);
      await handleFileUploadForApp(obj, obj);
      emit("uploadVoice", obj);
      uni.hideLoading();
    } catch (error) {
      uni.hideLoading();
      console.error("Error uploading voice:", error);
    }
  }

  // 重置
  voiceTime.value = "00:00";
};

// 停止录音
const endRecording = () => {
  recorderManager?.stop();
};

// 格式化数字为 2 位数
const padZero = (num: number) => {
  return num < 10 ? `0${num}` : `${num}`;
};

// 清理定时器
onUnmounted(() => {
  if (timer) clearInterval(timer);
});
onHide(() => {
  openVoiceFn(false, "open");
});

defineExpose({
  openVoiceFn,
});
</script>

<style scoped lang="scss">
@import "../../../static/scss/chat.scss";
</style>
